#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int res=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
	return res*f;
}
void write(int x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
int n,m;
struct Nene
{
	struct node
	{
		int nxt,to;
	}e[1000005<<1];
	int head[1000005],cnt_edge;
	void add_edge(int u,int v)
	{
		e[++cnt_edge].to=v;
		e[cnt_edge].nxt=head[u];
		head[u]=cnt_edge;
	}
	int siz[1000005],dep[1000005],dfn[1000005],cnt;
	void init(int u,int fa)
	{
		dep[u]=dep[fa]+1;
		siz[u]=1;
		dfn[u]=++cnt;
		for(int i=head[u];i;i=e[i].nxt)
		{
			int v=e[i].to;
			if(v==fa) continue;
			init(v,u);
			siz[u]+=siz[v];
		}
	}
}T[2];
struct Elaina
{
	int t[1000005];
	inline int lowbit(int x){return x&-x;}
	inline void add(int x,int v){for(;x<=n;x+=lowbit(x))t[x]+=v;}
	inline int Query(int x){int res=0;for(;x;x-=lowbit(x))res+=t[x];return res;}
	inline int query(int x,int y){return Query(y)-Query(x-1);}
}bit[2];
int rt,mnsiz,siz[1000005],vis[1000005],sum[1000005];
int a[1000005];
int pos[1000005];
void getrt(int u,int fa,int p)
{
	siz[u]=1;
	for(int i=T[1].head[u];i;i=T[1].e[i].nxt)
	{
		int v=T[1].e[i].to;
		if(v==fa||vis[v]) continue;
		getrt(v,u,p);
		siz[u]+=siz[v];
	}
	if(mnsiz>max(siz[u],sum[p]-siz[u])) mnsiz=max(siz[u],sum[p]-siz[u]),rt=u; 
}
const int mod=998244353;
int ans,ssiz,tsiz;
void dfs(int u,int fa,int p,int w)
{
	++sum[p];	
	ans=(ans+ssiz*sw[u]%mod*w)%mod;
	for(int i=T[1].head[u];i;i=T[1].e[i].nxt)
	{
		int v=T[1].e[i].to;
		if(vis[v]||v==fa) continue;
		dfs(v,u,p,w);
	}
}
void solve(int u)
{
	vis[u]=1;
	bit[0].add(dfn[pos[u]],siz[pos[u]]);
	bit[1].add(dfn[pos[u]],(n-siz[pos[u]]))
	for(int i=T[1].head[u];i;i=T[1].e[i].nxt)
	{
		int v=T[1].e[i].to;
		if(vis[v]) continue;
		sum[v]=tsiz=0;
		dfs(v,u,v,T[1].dep[u]);
		ssiz+=tsiz;
	}
	for(int i=T[1].head[u];i;i=T[1].e[i].nxt)
	{
		int v=T[1].e[i].to;
		if(vis[v]) continue;
		rt=0;mnsiz=1e9;
		getrt(v,u,v);
		solve(v);
	}
}
int main()
{
//	freopen("tree.in","r",stdin);
//	freopen("tree.out","w",stdout);
	n=read(),m=read();
	int r1,r2;
	for(int i=1;i<=n;i++) 
	{
		int x=read();
		if(!x) r1=i;
		else T[0].add_edge(x,i),T[0].add_edge(i,x);
	}
	for(int i=1;i<=m;i++)
	{
		int x=read();
		if(!x) r2=i;
		else T[1].add_edge(x,i),T[1].add_edge(i,x);
	}
	for(int i=1;i<=n;i++) a[i]=read(),pos[a[i]]=i;
	T[0].init(r1,0);T[1].init(r2,0);
	for(int i=1;i<=n;i++) sw[a[i]]=(sw[a[i]]+T[0].siz[i])%mod;
	mnsiz=1e9;sum[r2]=T[1].siz[r2];
	getrt(r2,0,r2);
	solve(r2);
	write(ans);
	return 0;
}

